package com.swanclouds.redfish.client;

import com.swanclouds.api.CloudProvider;
import com.swanclouds.api.RedfishClient;
import com.swanclouds.api.client.IOSClientBuilder;
import com.swanclouds.api.exceptions.AuthenticationException;
import com.swanclouds.core.transport.Config;
import com.swanclouds.redfish.common.Auth;
import com.swanclouds.redfish.identity.RedfishAuth;
import com.swanclouds.redfish.internal.OSAuthenticator;
import org.apache.http.auth.AuthScope;

public abstract class OSClientBuilder<R, T extends IOSClientBuilder<R, T>> implements IOSClientBuilder<R, T> {

    Config config;
    String endpoint;
    String user;
    String password;
    CloudProvider provider = CloudProvider.UNKNOWN;
    boolean loadVersion = false;

    @SuppressWarnings("unchecked")
    @Override
    public T withConfig(Config config) {
        this.config = config;
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T provider(CloudProvider provider) {
        this.provider = provider;
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T credentials(String user, String password) {
        this.user = user;
        this.password = password;
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T endpoint(String endpoint) {
        this.endpoint = endpoint;
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T useNonStrictSSLClient(boolean useNonStrictSSL) {
        if (config == null)
            config = Config.newConfig().withSSLVerificationDisabled();
        return (T) this;
    }

    /**
     * 是否加载 redfish 版本信息
     *
     * @param loadVersion load version in token
     * @return self for method chaining
     */
    @Override
    public T loadVersion(boolean loadVersion) {
        this.loadVersion = loadVersion;
        return (T) this;
    }

    public static class ClientV1 extends OSClientBuilder<RedfishClient.OSClientV1, V1> implements V1 {

        String domain;
        AuthScope scope;
        String tokenId;


        @Override
        public ClientV1 credentials(String user, String password, String domain) {
            this.user = user;
            this.password = password;
            this.domain = domain;
            return this;
        }

        @Override
        public ClientV1 token(String tokenId) {
            this.tokenId = tokenId;
            return this;
        }

        /**
         * 是否加载版本信息
         *
         * @param loadVersion loadVersion version in token
         * @return self for method chaining
         */
        @Override
        public V1 loadVersion(boolean loadVersion) {
            this.loadVersion = loadVersion;
            return this;
        }

        @Override
        public RedfishClient.OSClientV1 authenticate() throws AuthenticationException {
            // token based authentication
            if (tokenId != null && tokenId.length() > 0)
                return (RedfishClient.OSClientV1) OSAuthenticator.invoke(new RedfishAuth(tokenId), endpoint, config, provider,loadVersion);
            // credential based authentication
            if (user != null && user.length() > 0)
                return (RedfishClient.OSClientV1) OSAuthenticator.invoke(new RedfishAuth(user, password), endpoint, config, provider,loadVersion);
            // Use tokenless auth finally
            return (RedfishClient.OSClientV1) OSAuthenticator.invoke(new RedfishAuth(user,password, Auth.Type.TOKEN), endpoint, config, provider,loadVersion);
        }


    }
}